#include "head.h"
#include <iostream>
#include <sys/socket.h>

using std::cout;
using std::endl;

//接收确定的length个字节数的函数
int recvn(int sockfd, void * buff, int length)
{
    int left = length; 
    char * pbuf = (char*)buff;
    int ret = 0;
    while(left > 0) {
        ret = recv(sockfd, pbuf, left, 0);
        pbuf += ret;
        left -= ret;
    }
    return length - left;
}

int main()
{
    //1. 创建监听套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    cout << "sfd:" << sfd << endl;
    ERROR_CHECK(sfd, -1, "socket");
    
    //2. 服务器绑定网络地址
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(8001);
    serveraddr.sin_addr.s_addr = inet_addr("192.168.30.129");

    int ret = bind(sfd, 
        (const struct sockaddr*)&serveraddr, sizeof(serveraddr));
    ERROR_CHECK(ret, -1, "bind");

    //3. 进行监听
    ret = listen(sfd, 1);
    cout << "server is listening.\n";
    
    int newFd = accept(sfd, NULL, NULL);
    cout << "111, newFd:" << newFd << endl;
    ERROR_CHECK(newFd, -1, "accept");

    int length = 0;
    cout << ">> length:" << length << endl;
    char buff[1024] = {0};

    //4. 服务器希望执行2次recv操作
    cout << "sizeof(buff): " << sizeof(buff) << endl;
    //ret = recv(newFd, &length, 4, 0);//先接收4个字节的长度
    ret = recvn(newFd, &length, 4);//先接收4个字节的长度
    printf("1 recv ret: %d, length: %d\n", ret, length);
    //recv(newFd, buff, length, 0);//再接收length字节的数据
    recvn(newFd, buff, length);//再接收length字节的数据
    cout << "1 buff:" << buff << endl;

    memset(buff, 0, sizeof(buff));
    //ret = recv(newFd, &length, 4, 0);
    ret = recvn(newFd, &length, 4);
    printf("\n2 recv ret: %d, length: %d\n", ret, length);
    //recv函数无法保证每一次都能接收到length字节的长度的数据
    //ret = recv(newFd, buff, length, 0);
    ret = recvn(newFd, buff, length);
    cout << "2 buff:" << buff << endl;

    while(1);
    close(sfd);
    return 0;
}
